package com.fuyao.cloud.common.data.mybatis;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.fuyao.cloud.common.core.constant.CommonConstants;
import com.fuyao.cloud.common.security.service.CloudUser;
import com.fuyao.cloud.common.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.util.ClassUtils;

import java.nio.charset.Charset;
import java.time.LocalDateTime;

/**
 * MybatisPlus 自动填充配置
 *
 * @author L.cm
 */
@Slf4j
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        CloudUser user = SecurityUtils.getUser();

        if (ObjectUtil.isNotEmpty(user)) {
            setValue("createId", user.getId(), metaObject);
            setValue("createBy", getUserName(user), metaObject);

            setValue("deptId", user.getDeptId(), metaObject);
            setValue("deptFullname", user.getFullName(), metaObject);
            setValue("deptFullName", user.getFullName(), metaObject);
        }

        setValue("createTime", LocalDateTime.now(), metaObject);

        // 删除标记自动填充
        setValue("delFlag", CommonConstants.STATUS_NORMAL, metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        overwriteValue("updateTime", LocalDateTime.now(), metaObject);

        CloudUser user = SecurityUtils.getUser();
        if (user != null) {
            overwriteValue("updateId", user.getId(), metaObject);
            overwriteValue("updateBy", getUserName(user), metaObject);
        }
    }

    /**
     * 设置字段值，如果字段存在值不会覆盖
     * @param fieldName 属性名
     * @param fieldVal 属性值
     * @param metaObject MetaObject
     */
    private void setValue(String fieldName, Object fieldVal, MetaObject metaObject) {
        setValue(fieldName, fieldVal, metaObject, false);
    }

    /**
     * 设置字段值，如果字段存在值不会覆盖
     * @param fieldName 属性名
     * @param fieldVal 属性值
     * @param metaObject MetaObject
     */
    private void overwriteValue(String fieldName, Object fieldVal, MetaObject metaObject) {
        setValue(fieldName, fieldVal, metaObject, true);
    }

    /**
     * 填充值，先判断是否有手动设置，优先手动设置的值，例如：job 必须手动设置
     *
     * @param fieldName  属性名
     * @param fieldVal   属性值
     * @param metaObject MetaObject
     * @param overwrite  是否覆盖原有值,避免更新操作手动入参
     */
    private void setValue(String fieldName, Object fieldVal, MetaObject metaObject, boolean overwrite) {
        // 0. 如果填充值为空
        if (fieldVal == null) {
            return;
        }

        // 1. 没有 get 方法
        if (!metaObject.hasSetter(fieldName)) {
            return;
        }

        // 2. 如果用户有手动设置的值
        Object userSetValue = metaObject.getValue(fieldName);
        String setValueStr = StrUtil.str(userSetValue, Charset.defaultCharset());
        if (!overwrite && StrUtil.isNotBlank(setValueStr)) {
            return;
        }

        // 3. field 类型相同时设置
        Class<?> getterType = metaObject.getGetterType(fieldName);
        if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
            metaObject.setValue(fieldName, fieldVal);
        }
    }

    /**
     * 获取当前的用户名
     *
     * @return 当前用户名称
     */
    private String getUserName(CloudUser user) {
        if (user == null) {
            return StrUtil.EMPTY;
        }
        return StrUtil.nullToEmpty(user.getName());
    }
}
